"""
Case Type   : 系统内部使用工具
Case Name   : 在减容开始之后删除待减容备机与主机的用户互信
Create At   : 2022/03/03
Owner       : opentestcase018
Description :
    1.一主两备在减容备1过程中删除备1与主机用户互信
    2.恢复环境
Expect      :
    1.备机减容成功
    2.恢复成功
History     :
    2022-5-17 opentestcase039 优化用例，根据自动化连跑要求，修改用例为在源库上减容
"""
import os
import time
import unittest
from testcase.utils.ComThread import ComThread
from testcase.utils.Common import Common
from testcase.utils.Common import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro
COMMONSH = CommonSH("PrimaryDbUser")
Constant = Constant()


@unittest.skipIf(3 != COMMONSH.get_node_num(), '非1+2环境不执行')
class Tools(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.common = Common()
        self.log.info(f'----{os.path.basename(__file__)} start----')
        self.primary_root_node = Node('PrimaryRoot')
        self.primary_node = Node('PrimaryDbUser')
        self.standby1_root_node = Node('Standby1Root')
        self.standby1_node = Node('Standby1DbUser')
        self.standby2_root_node = Node('Standby2Root')
        self.standby2_node = Node('Standby2DbUser')
        self.com_root = CommonSH("PrimaryRoot")
        self.com_user = CommonSH("PrimaryDbUser")
        self.s_com1 = CommonSH("Standby1DbUser")
        self.s_com2 = CommonSH("Standby2DbUser")
        self.u_name = self.primary_node.ssh_user
        self.ssh_file = os.path.join('/home', self.u_name, 'hostfile')
        num = COMMONSH.get_node_num()
        self.assertGreaterEqual(num, 3, "执行失败:节点数量异常，减容不执行")

        self.log.info("查询synchronous_standby_names默认值")
        result = COMMONSH.execut_db_sql("show synchronous_standby_names")
        self.log.info(f"primary synchronous_standby_names is {result}")
        self.synchronous_standby_names_p = result.strip().splitlines()[-2]
        result = self.s_com1.execut_db_sql("show synchronous_standby_names")
        self.log.info(f"s1 synchronous_standby_names is {result}")
        self.synchronous_standby_names_s1 = result.strip().splitlines()[-2]
        result = self.s_com2.execut_db_sql("show synchronous_standby_names")
        self.log.info(f"s2 synchronous_standby_names is {result}")
        self.synchronous_standby_names_s2 = result.strip().splitlines()[-2]

        self.host_tuple = (self.primary_node.ssh_host,
                           self.standby1_node.ssh_host,
                           self.standby2_node.ssh_host)
        self.params = {'-f': 'test_hosts'}

    def test_gs_dropnode(self):
        text = '----step1:在对备1减容时删除备1与主机用户互信 expect:减容成功----'
        self.log.info(text)
        self.log.info('构建减容命令shell脚本前置条件')
        drop_cmd = f'gs_dropnode -U {self.u_name} -G {self.u_name} ' \
                   f'-h {self.standby1_node.ssh_host}'
        self.log.info(drop_cmd)
        global shell_path
        shell_path = os.path.join('/', 'home', f'{self.u_name}', 'dropnode.sh')
        shell_cmd = f'touch {shell_path};echo -e {drop_cmd} > {shell_path};' \
                    f'chmod 755 {shell_path};cat {shell_path}'
        self.log.info(shell_cmd)
        pri_shell_res = self.primary_root_node.sh(shell_cmd).result()
        self.log.info(pri_shell_res)
        self.log.info('对备1执行减容操作')
        drop_cmd = f'''source {macro.DB_ENV_PATH}
                   expect <<EOF
                   set timeout 200
                   spawn {shell_path}
                   expect "(yes/no)?"
                   send "yes\\n"
                   expect eof\n''' + '''EOF'''
        session_1 = ComThread(self.common.get_sh_result, args=(
            self.primary_node, drop_cmd,))
        session_1.setDaemon(True)
        self.log.info('在备1减容同时删除备1与主机用户互信')
        ssh_path = os.path.join('/', 'home', f'{self.u_name}', '.ssh')
        del_cmd = f'rm -rf {ssh_path}'
        session_2 = ComThread(self.common.get_sh_result, args=(
            self.standby1_root_node, del_cmd,))
        session_2.setDaemon(True)
        session_1.start()
        time.sleep(0.5)
        session_2.start()
        self.log.info('备1减容结果')
        session_1.join(120)
        session_1_result = session_1.get_result()
        self.log.info(session_1_result)
        self.log.info('备1互信删除结果')
        session_2.join(120)
        session_2_result = session_2.get_result()
        self.log.info(session_2_result)
        self.log.info('备1减容及备1删除互信结果')
        self.assertIn('Success to drop the target nodes', session_1_result,
                      text + '减容失败')
        self.assertEqual('', session_2_result, '备1用户互信删除失败')

        self.log.info('检查数据库是否减容')
        check_cmd = f'source {macro.DB_ENV_PATH};' \
                    f'gs_om -t status --detail;'
        self.log.info(check_cmd)
        check_res = self.primary_node.sh(check_cmd).result()
        self.log.info(check_res)
        check_lis = [self.primary_node.ssh_host, self.standby2_node.ssh_host]
        for info in check_lis:
            self.assertIn(info, check_res, '数据库状态检查失败')

    def tearDown(self):
        text = "----step2:恢复环境 expect:成功----"
        self.log.info(text)
        text = '----创建hostfile文件，添加主备IP信息,并修改文件属性----'
        self.log.info(text)
        add_cmd = f'touch {self.ssh_file};' \
                  f'chmod -R 755 {self.ssh_file};' \
                  f"echo -e '{self.primary_node.ssh_host}\n" \
                  f"{self.standby1_node.ssh_host}\n" \
                  f"{self.standby2_node.ssh_host}' > {self.ssh_file};" \
                  f"chown {self.u_name}:{self.u_name} {self.ssh_file};" \
                  f"cat {self.ssh_file}"
        self.log.info(add_cmd)
        add_res = self.primary_root_node.sh(add_cmd).result()
        self.log.info(add_res)

        self.log.info('-----创建root互信-----')
        self.com_root.exec_gs_sshexkey(macro.DB_SCRIPT_PATH,
                                       *self.host_tuple,
                                       **self.params)

        self.log.info('-----创建用户互信-----')
        ssh_cmd = f'''source {macro.DB_ENV_PATH}
                      expect <<EOF
                      set timeout 60
                      spawn gs_sshexkey -f {self.ssh_file};
                      expect "*assword:"
                      send "{macro.COMMON_PASSWD}\\n"
                      expect eof\n''' + '''EOF'''
        self.log.info(ssh_cmd)
        ssh_res = self.primary_node.sh(ssh_cmd).result()
        self.log.info(ssh_res)
        result = self.com_root.exec_expension(f"{self.primary_node.ssh_user}",
                                              f"{self.primary_node.ssh_user}",
                                              f"{self.standby1_node.ssh_host}",
                                              f"{macro.DB_XML_PATH}")
        self.log.info(result)
        self.log.info('-----删除创建文件-----')
        del_cmd = f"rm -rf {shell_path};rm -rf {self.ssh_file}"
        self.log.info(del_cmd)
        del_res = self.primary_root_node.sh(del_cmd).result()
        self.log.info(del_res)
        self.log.info("恢复各节点synchronous_standby_names")
        COMMONSH.execute_gsguc("reload",
                               Constant.GSGUC_SUCCESS_MSG,
                               f"synchronous_standby_names="
                               f"'{self.synchronous_standby_names_p}'",
                               single=True)
        self.s_com1.execute_gsguc("reload",
                                  Constant.GSGUC_SUCCESS_MSG,
                                  f"synchronous_standby_names="
                                  f"'{self.synchronous_standby_names_s1}'",
                                  single=True)
        self.s_com2.execute_gsguc("reload",
                                  Constant.GSGUC_SUCCESS_MSG,
                                  f"synchronous_standby_names="
                                  f"'{self.synchronous_standby_names_s2}'",
                                  single=True)
        self.assertIn('Successfully created SSH trust.', ssh_res, '用户互信创建失败')
        self.assertEqual('', del_res, '文件删除失败')
        self.assertTrue(result)
        self.assertIn(self.primary_node.ssh_host and
                      self.standby1_node.ssh_host and
                      self.standby2_node.ssh_host,
                      add_res, 'hostfile创建失败')
        self.log.info(f'----{os.path.basename(__file__)} finish----')
